/*
 * Description: performance hooking aspect.
 */
#ifndef ASPECT_H
#define ASPECT_H
#include <shellapi.h>
#include "performance/perf_scene.h"
#include "messenger.h"
#include <Windows.h>

namespace PERF {
    LONG AppendAspect();
    LONG RemoveAspect();
    BOOL WINAPI AspectedCreateProcessA(
        _In_opt_ LPCSTR lpApplicationName,
        _Inout_opt_ LPCSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOW lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation);
    BOOL WINAPI AspectedCreateProcessW(
        _In_opt_ LPCWSTR lpApplicationName,
        _Inout_opt_ LPCWSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCWSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOW lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation);
    BOOL WINAPI AspectedShellExecuteExW(
        SHELLEXECUTEINFOW* pExecInfo);


    void SendMessage(
        const std::string &appPath, const std::string &cmdline, DWORD pid);
    void SendMessageToServiceA(
        std::string applicationName, DWORD pid, std::string lpCommandLine);
    void SendMessageToServiceW(
        std::wstring applicationName, DWORD pid, std::wstring lpCommandLine);

    typedef BOOL(WINAPI* POriginalCreateProcessA)(
        _In_opt_ LPCSTR lpApplicationName,
        _Inout_opt_ LPCSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOW lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation);
    typedef BOOL(WINAPI* POriginalCreateProcessW)(
        _In_opt_ LPCWSTR lpApplicationName,
        _Inout_opt_ LPCWSTR lpCommandLine,
        _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
        _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
        _In_ BOOL bInheritHandles,
        _In_ DWORD dwCreationFlags,
        _In_opt_ LPVOID lpEnvironment,
        _In_opt_ LPCWSTR lpCurrentDirectory,
        _In_ LPSTARTUPINFOW lpStartupInfo,
        _Out_ LPPROCESS_INFORMATION lpProcessInformation);
    typedef BOOL(WINAPI* pfShellExecuteExW) (
        _Inout_ SHELLEXECUTEINFOW*);
    void SendMessageToService(const std::string& exeName);
    DWORD GetProcessIdByName(LPCTSTR exeName);
    std::string GetProcessPathByPid(DWORD processId);
    void SendMouseDragMessageToService(const std::string &exeName, const std::string &exePath);
}
#endif